<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref, computed } from 'vue'
import { useSensorStore } from './stores/sensorStore'
import SensorCard from './components/SensorCard.vue'
import DataStream from './components/DataStream.vue'
import ThresholdSettings from './components/ThresholdSettings.vue'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts'
import axios from 'axios'

const store = useSensorStore()

// WebSocket 连接
let socket: WebSocket | null = null

const initWebSocket = () => {
  socket = new WebSocket('ws://localhost:8080/ws/device-data')

  socket.onopen = () => store.setConnectionStatus('connected')
  socket.onclose = () => {
    store.setConnectionStatus('disconnected')
    // 增加重连机制
    setTimeout(() => {
      console.log('尝试重新连接 WebSocket...')
      initWebSocket()
    }, 5000) // 5秒后重试
  }
  socket.onerror = () => store.setConnectionStatus('disconnected')

  socket.onmessage = (event) => {
    try {
      const data = JSON.parse(event.data)
      // 确保数据格式与 store.updateData 兼容
      store.updateData({
        temperature: data.temperature,
        humidity: data.humidity,
        light: data.light,
        createTime: data.createTime
      })
      const localThresholds = localStorage.getItem('thresholds')
      if (localThresholds) {
        thresholds.value = JSON.parse(localThresholds)
      }
      // 判断数据是否在合法范围内，并更新 isAlarm 状态
      const temperatureAlarm = store.temperature !== null &&
        (parseFloat(store.temperature) < thresholds.value.temperature?.min ||
          parseFloat(store.temperature) > thresholds.value.temperature?.max)
      const humidityAlarm = store.humidity !== null &&
        (parseFloat(store.humidity) < thresholds.value.humidity?.min ||
          parseFloat(store.humidity) > thresholds.value.humidity?.max)
      const lightAlarm = store.light !== null &&
        (parseFloat(store.light) < thresholds.value.light?.min ||
          parseFloat(store.light) > thresholds.value.light?.max)
      isAlarm.value = {
        temperature: temperatureAlarm,
        humidity: humidityAlarm,
        light: lightAlarm
      }
    } catch (error) {
      console.error('数据解析错误:', error)
    }
  }
}

// 指令发送
const sendCommand = async (type: string) => {
  try {
    const response = await fetch(`/api/device/${type}`, { method: 'POST' })
    const result = await response.json()
    if (result.code === -1) {
      alert(result.msg)
    }
  } catch (error) {
    console.error('指令发送失败:', error)
    if (error instanceof TypeError && error.message.includes('Failed to fetch')) {
      ElMessage.message('网络请求失败，请检查网络连接')
    } else {
      ElMessage.error('指令发送失败')
    }
  }
}

// 防抖处理
const debounce = (fn: Function, delay = 1000) => {
  let timer: number
  return (...args: any[]) => {
    clearTimeout(timer)
    timer = setTimeout(() => fn(...args), delay)
  }
}

const commands = {
  temperature: debounce(() => sendCommand('temperature')),
  humidity: debounce(() => sendCommand('humidity')),
  light: debounce(() => sendCommand('light'))
}

// 获取阈值
const thresholds = ref<{ [key: string]: { min: number, max: number } }>({})
const errorMsg = ref<string>('')

const fetchThresholds = async () => {
  try {
    // 尝试从本地存储获取阈值
    const localThresholds = localStorage.getItem('thresholds')
    if (localThresholds) {
      thresholds.value = JSON.parse(localThresholds)
      return
    }

    const response = await fetch('/api/threshold')
    if (!response.ok) {
      throw new Error('Network response was not ok')
    }
    const data = await response.json()
    console.log(data)
    if (data.thresholds) {
      data.thresholds.forEach((threshold: any) => {
        const type = threshold.parameterType === 0 ? 'temperature' : threshold.parameterType === 1 ? 'humidity' : 'light'
        thresholds.value[type] = { min: parseInt(threshold.minValue), max: parseInt(threshold.maxValue) }
      })
      // 将获取到的阈值存储到本地存储
      localStorage.setItem('thresholds', JSON.stringify(thresholds.value))
    } else {
      errorMsg.value = data.msg
    }
  } catch (error) {
    console.error('获取阈值失败:', error)
  }
}

// 使用 reactive 定义 isAlarm，使其可变
const isAlarm = ref<{ [key: string]: boolean }>({
  temperature: false,
  humidity: false,
  light: false
})

// 生命周期
onMounted(() => {
  fetchThresholds().then(() => {
    initWebSocket()
  })
})

onBeforeUnmount(() => {
  if (socket && socket.readyState === WebSocket.OPEN) {
    socket.close()
  } else {
    console.log('WebSocket 已关闭或未连接，无需关闭')
  }
})

const showTemperatureChart = ref(false)
const showHumidityChart = ref(false)
const showLightChart = ref(false)

const temperatureChart = ref<HTMLElement | null>(null)
const humidityChart = ref<HTMLElement | null>(null)
const lightChart = ref<HTMLElement | null>(null)

const navigateToChart = async () => {
  showTemperatureChart.value = true
  showHumidityChart.value = true
  showLightChart.value = true

  const data = await fetchData()
  if (data && data.length > 0) {
    initTemperatureChart(data)
    initHumidityChart(data)
    initLightChart(data)
  }
}

const initTemperatureChart = (data: any[]) => {
  if (temperatureChart.value) {
    const myChart = echarts.init(temperatureChart.value)
    const processedData = data.map((item: { temperature: string; createTime: string }) => ({
      createTime: item.createTime,
      temperature: parseFloat(item.temperature.replace('℃', ''))
    }))

    const option = {
      title: {
        text: '温度变化图'
      },
      tooltip: {
        trigger: 'axis'
      },
      xAxis: {
        type: 'category',
        data: processedData.map((item: { createTime: string }) => item.createTime)
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          name: '温度',
          type: 'line',
          color: '#FF6384',
          data: processedData.map((item: { temperature: number }) => item.temperature)
        }
      ]
    }
    myChart.setOption(option)
  }
}

const initHumidityChart = (data: any[]) => {
  if (humidityChart.value) {
    const myChart = echarts.init(humidityChart.value)
    const processedData = data.map((item: { humidity: string; createTime: string }) => ({
      createTime: item.createTime,
      humidity: parseFloat(item.humidity.replace('%', ''))
    }))

    const option = {
      title: {
        text: '湿度变化图'
      },
      tooltip: {
        trigger: 'axis'
      },
      xAxis: {
        type: 'category',
        data: processedData.map((item: { createTime: string }) => item.createTime)
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          name: '湿度',
          type: 'line',
          color: '#36A2EB',
          data: processedData.map((item: { humidity: number }) => item.humidity)
        }
      ]
    }
    myChart.setOption(option)
  }
}

const initLightChart = (data: any[]) => {
  if (lightChart.value) {
    const myChart = echarts.init(lightChart.value)
    const processedData = data.map((item: { light: string | null; createTime: string }) => ({
      createTime: item.createTime,
      light: item.light === null ? 0 : parseFloat(item.light.replace('lux', ''))
    }))

    const option = {
      title: {
        text: '光照变化图'
      },
      tooltip: {
        trigger: 'axis'
      },
      xAxis: {
        type: 'category',
        data: processedData.map((item: { createTime: string }) => item.createTime)
      },
      
      yAxis: {
        type: 'value'
      },
      series: [
        {
          name: '光照',
          type: 'line',
          color: '#FFCE56',
          data: processedData.map((item: { light: number }) => item.light)
        }
      ]
    }
    myChart.setOption(option)
  }
}

const fetchData = async () => {
  try {
    const response = await axios.get('/api/device/all')
    const data = response.data;
    if (!data || data.length === 0) {
      console.warn('数据为空');
      return [];
    }
    return data;
  } catch (error) {
    console.error('获取数据失败:', error);
    return [];
  }
}
</script>

<template>
  <div class="container py-5 bg-light">
    <h1 class="mb-4 text-center">
      <i class="bi bi-motherboard"></i> 智能环境监测系统
      <span :class="{
        'status-indicator': true,
        'bg-success': store.connectionStatus === 'connected',
        'bg-danger': store.connectionStatus === 'disconnected'
      }"></span>
    </h1>
    <div class="row g-4 mb-4">
      <div class="col-md-4" @click="commands.temperature()">
        <SensorCard title="温度" :value="store.temperature" unit="℃" icon-class="bi-thermometer-sun"
          color-class="text-danger" :isAlarm="isAlarm.temperature" />
      </div>

      <div class="col-md-4" @click="commands.humidity()">
        <SensorCard title="湿度" :value="store.humidity" unit="%" icon-class="bi-droplet" color-class="text-primary"
          :isAlarm="isAlarm.humidity" />
      </div>

      <div class="col-md-4" @click="commands.light()">
        <SensorCard title="光照" :value="store.light" unit="lux" icon-class="bi-brightness-high"
          color-class="text-warning" :isAlarm="isAlarm.light" />
      </div>
    </div>

    <div class="d-flex justify-content-end">
      <button type="button" class="btn btn-outline-primary btn-lg" @click="navigateToChart">查看统计报表</button>
    </div>

    <div v-if="showTemperatureChart" ref="temperatureChart" style="inline-size: 100%; block-size: 400px;"></div>
    <div v-if="showHumidityChart" ref="humidityChart" style="inline-size: 100%; block-size: 400px;"></div>
    <div v-if="showLightChart" ref="lightChart" style="inline-size: 100%; block-size: 400px;"></div>

    <DataStream :items="store.dataStream" />
    <ThresholdSettings :thresholds="thresholds" />
  </div>
</template>

<style>
@import 'bootstrap/dist/css/bootstrap.min.css';
@import 'bootstrap-icons/font/bootstrap-icons.css';

.status-indicator {
  inline-size: 15px;
  block-size: 15px;
  border-radius: 50%;
  display: inline-block;
  vertical-align: middle;
}
</style>